package com.aurora.base.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class Merge {

	public static Class[] types = { Integer.class, Long.class, Double.class, String.class, Float.class, Byte.class, Boolean.class, Character.class, int.class, long.class,
			double.class, float.class, byte.class, boolean.class, char.class, Enum.class };

	public static Object merge(Object newObject, Object oldObject) {
		if (oldObject == null) {
			return newObject;
		}
		if (newObject == null) {
			return oldObject;
		}
		Class class1 = oldObject.getClass();
		Field[] fields = class1.getDeclaredFields();
		ArrayList<Field> fieldArrayList = new ArrayList<Field>();
		for (Field field : fields) {
			fieldArrayList.add(field);
		}
		Class superClass = class1.getSuperclass();
		while (true) {
			Field[] superFields = superClass.getDeclaredFields();
			for (Field field : superFields) {
				fieldArrayList.add(field);
			}
			superClass = superClass.getSuperclass();
			if (superClass == Object.class) {
				break;
			}
		}

		for (Field field : fieldArrayList) {
			String name = field.getName();
			if (name.equals("serialVersionUID")) {
				continue;
			}
			Class fieldType = field.getType();
			try {
				Method setMethod = class1.getMethod("set" + name.substring(0, 1).toUpperCase() + name.substring(1, name.length()), fieldType);
				Method getMethod = class1.getMethod("get" + name.substring(0, 1).toUpperCase() + name.substring(1, name.length()));
				Object value = getMethod.invoke(newObject);
				if (value != null) {
					if (judge(value)) {
						setMethod.invoke(oldObject, value);
					} else {
						Object mergeObject = merge(getMethod.invoke(newObject), getMethod.invoke(oldObject));
						setMethod.invoke(oldObject, mergeObject);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return oldObject;
	}

	public static boolean judge(Object object) {
		boolean bool = false;
		for (Class type : types) {
			if (object.getClass() == type) {
				bool = true;
				break;
			}

		}
		if (object instanceof Enum) {
			bool = true;
		}
		return bool;
	}

	public static void main(String[] args) throws Exception {

	}

}
